package com.ruoyi.common.core.utils;

import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 通用工具类
 */
public class CommUtil {
    
    /**
     * 金额类精度
     */
    private static final int MONEY_SCALE = 3;
    
    /**
     * 利率类精度
     */
    private static final int RATE_SCALE = 7;
    
    /**
     * 默认除法精度
     */
    private static final int DIV_SCALE = 50;
    
    /**
     * 零金额
     */
    private static final BigDecimal MONEY_ZERO = BigDecimal.ZERO;
    
    /**
     * 空串
     */
    private static final String STRING_NULL = "";


    public static String removeSpeSym(Object str) {
        if (str != null && str instanceof String) {
            str = str.toString().replace('"', ' ');
            str = str.toString().replace("*", "");
            str = str.toString().replace("\\", "");
            str = str.toString().replace("'", "");
            str = str.toString().replace(" ", "");
            str = str.toString().replace("　", "");
            str = str.toString().trim();
            return str.toString();
        } else {
            return "";
        }
    }

    public static String removeEscChar(Object str) {
        if (str != null && str instanceof String) {
            Object strObj = str.toString().replace('"', ' ');
            strObj = strObj.toString().replace("\\", "");
            strObj = strObj.toString().replace("'", "");
            strObj = strObj.toString().replace(" ", "");
            strObj = strObj.toString().replace("　", "");
            return strObj.toString();
        } else {
            return "";
        }
    }

    /**
     * 移除金额里面的-，
     * @param str
     * @return
     */
    public static String removeAmountSym(String str) {
        if (str != null) {
            str = str.replace(",", "");
            str = str.replace("-", "");
            str = str.trim();
        }

        return str;
    }

    /**
     * 判断字符串是否为数字型。
     *
     * @param str
     * @return true/false
     */
    public static boolean isNumeric(String str) {
		if (str == null || str.length() == 0) {
			return false;
		}
        for (int i = 0; i < str.length(); i++) {
            if (!Character.isDigit(str.charAt(i))) {
                return false;
            }
        }
        return true;
    }
    
    /**
     * 判断value是否为空
     *
     * @param value
     * @return true/false
     */
    public static boolean isNull(String value) {
        return null == value;
    }
   /**

     * 判断对象或对象数组中每一个对象是否为空: 对象为null，字符序列长度为0，集合类、Map为empty
     *
     * @param obj
     * @return
     */
    public static boolean isNullOrEmpty(Object obj) {
        if (obj == null)
            return true;

        if (obj instanceof CharSequence)
            return ((CharSequence) obj).length() == 0;

        if (obj instanceof Collection)
            return ((Collection) obj).isEmpty();

        if (obj instanceof Map)
            return ((Map) obj).isEmpty();

        if (obj instanceof Object[]) {
            Object[] object = (Object[]) obj;
            if (object.length == 0) {
                return true;
            }
            boolean empty = true;
            for (int i = 0; i < object.length; i++) {
                if (!isNullOrEmpty(object[i])) {
                    empty = false;
                    break;
                }
            }
            return empty;
        }
        return false;
    }

    /**
     * 判断对象是否为空，且对象的所有属性都为空
     * ps: boolean类型会有默认值false 判断结果不会为null 会影响判断结果
     * 序列化的默认值也会影响判断结果
     *
     * @param object
     * @return
     */
    public static boolean objCheckIsNull(Object object) {
        Class clazz = object.getClass(); // 得到类对象
        Field fields[] = clazz.getDeclaredFields(); // 得到所有属性
        boolean flag = true; // 定义返回结果，默认为true
        for (Field field : fields) {
            field.setAccessible(true);
            Object fieldValue = null;
            try {
                flag = isEmpty(field.get(object)); // 得到属性值
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            if (!flag) { // 只要有一个属性值不为null 就返回false 表示对象不为null
                flag = false;
                break;
            }
        }
        return flag;
    }

    /**
     * 判断Object是否为空
     *
     * @param object
     * @return true/false
     */
    public static boolean isEmpty(Object object) {
        if (object instanceof String) {
            return isEmpty((String) object);
        } else if (object instanceof List) {
            return isEmpty((List) object);
        } else if (object instanceof Map) {
            return isEmpty((Map) object);
        }
        else if (object instanceof Object[]) {
            Object[] objectTmp = (Object[]) object;
            if (objectTmp.length == 0) {
                return true;
            }
            boolean empty = true;
            for (int i = 0; i < objectTmp.length; i++) {
                if (!isEmpty(objectTmp[i])) {
                    empty = false;
                    break;
                }
            }
            return empty;
        }
        else {
            return null == object;
        }
    }
    
    /**
     * 判断Object数组是否为空
     *
     * @param objects
     * @return true/false
     */
    public static boolean isEmpty(Object[] objects) {
        return null == objects || objects.length == 0;
    }
    
    /**
     * 判断Object是否不为空
     *
     * @param object
     * @return true/false
     */
    public static boolean isNotEmpty(Object object) {
        return !isEmpty(object);
    }
    
    /**
     * 判断Object数组是否不为空
     *
     * @param objects
     * @return true/false
     */
    public static boolean isNotEmpty(Object[] objects) {
        return !isEmpty(objects);
    }
    
    /**
     * 判断String是否为空
     *
     * @param str
     * @return true/false
     */
    public static boolean isEmpty(String str) {
        return null == str || 0 == str.trim().length();
    }
    
    /**
     * 判断String是否不为空
     *
     * @param str
     * @return true/false
     */
    public static boolean isNotEmpty(String str) {
        return str != null && str.trim().length() > 0;
    }
    
    /**
     * 判断List是否为空
     *
     * @param list
     * @return true/false
     */
    public static boolean isEmpty(List list) {
        return null == list || 0 == list.size();
    }
    
    /**
     * 判断List是否不为空
     *
     * @param list
     * @return true/false
     */
    public static boolean isNotEmpty(List list) {
        return !isEmpty(list);
    }
    
    /**
     * 判断Map是否为空
     *
     * @param map
     * @return true/false
     */
    public static boolean isEmpty(Map map) {
        return null == map || 0 == map.size();
    }
    
    /**
     * 判断Map是否不为空
     *
     * @param map
     * @return true/false
     */
    public static boolean isNotEmpty(Map map) {
        return !isEmpty(map);
    }
    
    /**
     * 组成字符串方法
     *
     * @param value 变参
     * @return String
     */
    public static BigDecimal toBigDecimal(Object value) {
		if (value == null) {
			return BigDecimal.ZERO;
		}
        if (value instanceof BigDecimal) {
            return (BigDecimal) value;
        } else if (value instanceof Double) {
            String s = String.format("%f", (Double) value);
            return new BigDecimal(s);
        } else if (value instanceof Float) {
            String s = String.format("%f", (Float) value);
            return new BigDecimal(s);
        } else if (value instanceof Long) {
            String s = String.format("%d", (Long) value);
            return new BigDecimal(s);
        } else if (value instanceof Integer) {
            String s = String.format("%d", (Integer) value);
            return new BigDecimal(s);
        } else if (value instanceof String) {
            if (isEmpty((String)value)) {
                return BigDecimal.ZERO;
            }
            return new BigDecimal(removeAmountSym((String)value));
        } else {
            return new BigDecimal(value.toString());
        }
    }
    
    /**
     * 转换成Integer
     *
     * @param value
     * @return Integer
     */
    public static Integer toInteger(Object value) {
        if (value == null) {
            return null;
        }
        if (value instanceof Integer) {
            return (Integer) value;
        } else {
            try {
                return new Integer(value.toString());
            } catch (Exception e) {
                return null;
            }
        }
    }
    
    /**
     * BigDecimal转换成Long, 如果BigDecimal包含有效小数位，则会报错。
     *
     * @param value
     * @return Long
     */
    public static Long toLong(BigDecimal value) {
        if (value == null) {
            return null;
        }
        return value.longValueExact();
    }
    
    /**
     * 转换成Long
     *
     * @param   value
     * @return Long
     */
    public static Long toLong(Object value) {
        if (value == null) {
            return null;
        }
        if (value instanceof Long) {
            return (Long) value;
        } else {
            try {
                return new Long(value.toString());
            } catch (Exception e) {
                return null;
            }
        }
    }

    /**
     * value的toString方法
     *
     * @param value
     * @return String
     */
    public static String toString(Object value) {
        if (isEmpty(value)) {
            return null;
        }

        if( value instanceof String){
            return String.valueOf(value);
        }
        else if( value instanceof Date  ){
            return String.valueOf(value);
        }
        else if ( value instanceof BigDecimal){
            return String.valueOf(value);
        }
        else if ( value instanceof Integer  ){
            return String.valueOf(value);
        }
        else if ( value instanceof Long ){
            return String.valueOf(value);
        }
        else {
            return String.valueOf(value);
        }
    }

    /**
     * Array的toString方法
     *
     * @param array
     * @return String
     */
    public static String toString(Object[] array) {
		if (array == null) {
			return null;
		}
        String out = array.getClass().getSimpleName() + " [";
        for (int ii = 0; ii < array.length; ii++) {
            out += array[ii];
			if (ii + 1 < array.length) {
				out += ",";
			}
        }
        out += "]";
        return out;
    }
    
    /**
     * Map的toString方法
     *
     * @param map
     * @return String
     */
    public static String toString(Map<?, ?> map) {
		if (map == null) {
			return null;
		}
        String out = map.getClass().getSimpleName() + " {";
        Iterator<?> iter = map.keySet().iterator();
        while (iter.hasNext()) {
            Object key = iter.next();
            Object value = map.get(key);
            out += key + "=" + value;
			if (iter.hasNext()) {
				out += ",";
			}
        }
        out += "}";
        return out;
    }
    
    /**
     * List的toString方法
     *
     * @param list
     * @return String
     */
    public static String toString(List list) {
		if (list == null) {
			return null;
		}
        String out = list.getClass().getSimpleName() + " [";
        for (int ii = 0; ii < list.size(); ii++) {
            out += list.get(ii);
			if (ii + 1 < list.size()) {
				out += ",";
			}
        }
        out += "]";
        return out;
    }
    
    /**
     * Set的toString方法
     *
     * @param set
     * @return String
     */
    public static String toString(Set set) {
		if (set == null) {
			return null;
		}
        String out = set.getClass().getSimpleName() + " [";
        int ii = 0;
        for (Object o : set) {
            out += o;
			if (++ii + 1 < set.size()) {
				out += ",";
			}
        }
        out += "]";
        return out;
    }
    
    /**
     * 获取BigDecimal整数位值
     *
     * @param bd
     * @return Long
     */
    public static Long longValue(BigDecimal bd) {
        return bd.longValue();
    }
    
    /**
     * 获取BigDecimal小数位值
     *
     * @param bd
     * @return igDecimal
     */
    public static BigDecimal decimalValue(BigDecimal bd) {
        return bd.subtract(new BigDecimal(bd.longValue()));
    }
    
    /**
     * 数组转成List. (List转Array则直接使用List.toArray())
     *
     * @param array
     * @return List
     */
    public static final List<Object> arrayToList(Object[] array) {
        ArrayList<Object> list = new ArrayList<Object>();
		for (int i = 0; i < array.length; i++) {
			list.add(array[i]);
		}
        return list;
    }
    
    /**
     * String对象比较.
     *
     * @param obj1
     * @param obj2
     * @return 0 equal,-n 小于, n 大于。
     */
    public static int compare(String obj1, String obj2) {
		if (obj1 == null && obj2 == null) {
			return 0;
		}
		if (obj1 == null) {
			obj1 = "";
		}
		if (obj2 == null) {
			obj2 = "";
		}
        return obj1.compareTo(obj2);
    }
    
    /**
     * Long对象比较.
     *
     * @param obj1
     * @param obj2
     * @return 0 equal,-n 小于, n 大于。
     */
    public static int compare(Long obj1, Long obj2) {
		if (obj1 == null && obj2 == null) {
			return 0;
		}
		if (obj1 == null) {
			return -1;
		}
		if (obj2 == null) {
			return 1;
		}
        return obj1.compareTo(obj2);
    }
    
    /**
     * Integer对象比较.
     *
     * @param obj1
     * @param obj2
     * @return 0 equal,-n 小于, n 大于。
     */
    public static int compare(Integer obj1, Integer obj2) {
		if (obj1 == null && obj2 == null) {
			return 0;
		}
		if (obj1 == null) {
			return -1;
		}
		if (obj2 == null) {
			return 1;
		}
        return obj1.compareTo(obj2);
    }
    
    
    /**
     * 金额对象比较，BigDecimal，常量MONEY_ZERO表示金额0.00。
     *
     * @param money1
     * @param money2
     * @return 0 equal,-n 小于, n 大于。
     */
    public static int compareMoney(BigDecimal money1, BigDecimal money2) {
		if (money1 == null && money2 == null) {
			return 0;
		}
		if (money1 == null) {
			return -1;
		}
		if (money2 == null) {
			return 1;
		}
        
        BigDecimal m1 = money1.setScale(MONEY_SCALE, BigDecimal.ROUND_HALF_UP);
        BigDecimal m2 = money2.setScale(MONEY_SCALE, BigDecimal.ROUND_HALF_UP);
        return m1.compareTo(m2);
    }
    
    /**
     * 利率对象比较，BigDecimal，常量RATE_ZERO表示利率0.0000000。
     *
     * @param rate1
     * @param rate2
     * @return 0 equal,-n 小于, n 大于。
     */
    public static int compareRate(BigDecimal rate1, BigDecimal rate2) {
		if (rate1 == null && rate2 == null) {
			return 0;
		}
		if (rate1 == null) {
			return -1;
		}
		if (rate2 == null) {
			return 1;
		}
        
        BigDecimal m1 = rate1.setScale(RATE_SCALE, BigDecimal.ROUND_HALF_UP);
        BigDecimal m2 = rate2.setScale(RATE_SCALE, BigDecimal.ROUND_HALF_UP);
        return m1.compareTo(m2);
    }
    
    /**
     * 指定精度比较，BigDecimal
     *
     * @param money1
     * @param money2
     * @param scale 精度
     * @return 0 equal,-n 小于, n 大于。
     */
    public static int compareWithScale(BigDecimal money1, BigDecimal money2, int scale) {
		if (money1 == null && money2 == null) {
			return 0;
		}
		if (money1 == null) {
			return -1;
		}
		if (money2 == null) {
			return 1;
		}
	
		if (scale < 0) {
			scale = DIV_SCALE;
		}
        BigDecimal m1 = money1.setScale(scale, BigDecimal.ROUND_HALF_UP);
        BigDecimal m2 = money2.setScale(scale, BigDecimal.ROUND_HALF_UP);
        return m1.compareTo(m2);
    }
    
    
    /**
     * 判断两个String是否相等.
     *
     * @param obj1
     * @param obj2
     * @return
     */
    public static boolean equals(String obj1, String obj2) {
        return compare(obj1, obj2) == 0;
    }
    
    /**
     * 判断两个Long是否相等.
     *
     * @param obj1
     * @param obj2
     * @return
     */
    public static boolean equals(Long obj1, Long obj2) {
        return compare(obj1, obj2) == 0;
    }
    
    /**
     * 判断两个Integer是否相等.
     *
     * @param obj1
     * @param obj2
     * @return
     */
    public static boolean equals(Integer obj1, Integer obj2) {
        return compare(obj1, obj2) == 0;
    }
    
    
    
    /**
     * 判断两个金额是否相等.
     *
     * @param money1
     * @param money2
     * @return true/false
     */
    public static boolean equalsMoney(BigDecimal money1, BigDecimal money2) {
        return compareMoney(money1, money2) == 0;
    }
    
    /**
     * 判断金额是否为零(MONEY_ZERO).
     *
     * @param money1
     * @return true/false
     */
    public static boolean equalsMoneyZero(BigDecimal money1) {
        return compareMoney(money1, MONEY_ZERO) == 0;
    }
    
    
    /**
     * 判断两个BigDecimal是否不相等.
     *
     * @param obj1
     * @param obj2
     * @return
     */
    public static boolean notEquals(BigDecimal obj1, BigDecimal obj2) {
        return compareMoney(obj1, obj2) != 0;
    }
    
    /**
     * 判断两个String是否不相等.
     *
     * @param obj1
     * @param obj2
     * @return
     */
    public static boolean notEquals(String obj1, String obj2) {
        return compare(obj1, obj2) != 0;
    }
    
    /**
     * 判断两个Long是否不相等.
     *
     * @param obj1
     * @param obj2
     * @return
     */
    public static boolean notEquals(Long obj1, Long obj2) {
        return compare(obj1, obj2) != 0;
    }
    
    /**
     * 判断两个Integer是否不相等.
     *
     * @param obj1
     * @param obj2
     * @return
     */
    public static boolean notEquals(Integer obj1, Integer obj2) {
        return compare(obj1, obj2) != 0;
    }
    
    
    /**
     * BigDecimal的加法
     *
     * @param args BigDecimal可变参数
     * @return BigDecimal
     */
    public static BigDecimal plus(BigDecimal... args) {
		if (args == null) {
			return null;
		}
        BigDecimal bd = null;
        
        for (BigDecimal bigD : args) {
			if (bigD == null) {
				continue;
			}
			if (bd == null) {
				bd = bigD;
			} else {
				bd = bd.add(bigD);
			}
        }
        return bd;
    }
    
    /**
     * BigDecimal的减法
     *
     * @param args BigDecimal可变参数
     * @return BigDecimal
     */
    public static BigDecimal subtract(BigDecimal... args) {
		if (args == null) {
			return null;
		}
        BigDecimal bd = null;
        
        for (BigDecimal bigD : args) {
			if (bigD == null) {
				continue;
			}
			if (bd == null) {
				bd = bigD;
			} else {
				bd = bd.subtract(bigD);
			}
        }
        return bd;
    }
    
    /**
     * BigDecimal的乘法
     *
     * @param args BigDecimal可变参数
     * @return BigDecimal
     */
    public static BigDecimal multiply(BigDecimal... args) {
		if (args == null) {
			return null;
		}
        BigDecimal bd = null;
        
        for (BigDecimal bigD : args) {
			if (bigD == null) {
				continue;
			}
			if (bd == null) {
				bd = bigD;
			} else {
				bd = bd.multiply(bigD);
			}
        }
        return bd;
    }
    
    /**
     * BigDecimal的乘法
     *
     * @param scale 结果精度.
     * @param args BigDecimal可变参数
     * @return BigDecimal
     */
    public static BigDecimal multiply(int scale, BigDecimal... args) {
        BigDecimal bdo = null;
        BigDecimal bd = multiply(args);
		if (bd != null) {
			bdo = bd.setScale(scale, BigDecimal.ROUND_HALF_UP);
		} else {
			bdo = bd;
		}
        return bdo;
    }
    
    /**
     * BigDecimal的除法。
     *
     * @param args BigDecimal可变参数
     * @return BigDecimal
     */
    public static BigDecimal divide(BigDecimal... args) {
		if (args == null) {
			return null;
		}
        BigDecimal bd = null;
        
        for (BigDecimal bigD : args) {
			if (bigD == null) {
				continue;
			}
			if (bd == null) {
				bd = bigD;
			} else {
				bd = bd.divide(bigD, DIV_SCALE, BigDecimal.ROUND_HALF_UP);
			}
        }
        return bd;
    }
    
    /**
     * BigDecimal的除法。
     *
     * @param scale 结果精度
     * @param args BigDecimal可变参数
     * @return BigDecimal
     */
    public static BigDecimal divide(int scale, BigDecimal... args) {
        BigDecimal bdo = null;
        BigDecimal bd = divide(args);
		if (bd != null) {
			bdo = bd.setScale(scale, BigDecimal.ROUND_HALF_UP);
		} else {
			bdo = bd;
		}
        return bdo;
    }
    
    public static boolean contains(String[] arr, String str) {
		if (isEmpty(arr)) {
			return false;
		}
		if (isEmpty(str)) {
			return false;
		}
        for (String s : arr) {
			if (s.equals(str)) {
				return true;
			}
        }
        return false;
    }
    
    /**
     *使用基础指标对应值替换字符串公式
     * @param formula
     * @param parmMp
     * @return 替换后的公式
     */
    public static String replaceParms(String formula, Map<String, String> parmMp) {
        for (Map.Entry<String, String> entry : parmMp.entrySet()) {
            formula = formula.replace(entry.getKey(), entry.getValue());
        }
        return formula;
    }
    
    /**
     *返回科目金额
     * @param mapPrdAmt
     * @param sbjTp
     * @return 替换后的公式
     */
    public static BigDecimal getSubjAmt(Map<String, BigDecimal> mapPrdAmt, String sbjTp) {
        return mapPrdAmt.get(sbjTp) == null ? BigDecimal.ZERO : mapPrdAmt.get(sbjTp);
    }
    
    /**
     *统计科目总金额
     * @param mapMap
     * @return 替换后的公式
     */
    public static BigDecimal getSubjSumAmt(Map<Integer, Map<String, BigDecimal>> mapMap) {
        BigDecimal sum = BigDecimal.ZERO;
        if (isNotEmpty(mapMap)) {
            for (Map<String, BigDecimal> map : mapMap.values()) {
                if (isNotEmpty(map)) {
                    for (BigDecimal amt : map.values()) {
                        sum = CommUtil.plus(sum, amt);
                    }
                }
            }
        }
        return sum;
    }
    
    /**
     *获取最大KEY
     * @param mapMap
     * @return 替换后的公式
     */
    public static Integer getMaxKey(Map<Integer, Map<String, BigDecimal>> mapMap) {
        Integer maxKey = 0;
        if (isNotEmpty(mapMap)) {
            for (Integer key : mapMap.keySet()) {
                if (maxKey<key){
                    maxKey = key;
                }
            }
        }
        return maxKey;
    }

    /**
     * 对金额进行整数化
     *
     * @param amt
     *            金额
     * @param intUnit
     *            整数化单位类型
     * @param roundingModes
     *            整数化方法
     * @return 整数化后的金额
     */
    public static BigDecimal parseAmt(BigDecimal amt, Long intUnit, int roundingModes) {

        RoundingMode roundingMode = transRounding(roundingModes); // 获得整数化方法
        if (roundingMode == null) {
            //TODO
            throw new RuntimeException("");
        }
        amt = amt.setScale(intUnit.intValue(), roundingMode);
        return amt; // 进行整数化
    }

    /**
     * 转换小数点保留模式
     *
     * @param roundingMode
     * @return
     */

    public static RoundingMode transRounding(int roundingMode) {
        RoundingMode mode = null;
        switch (roundingMode) {
            case BigDecimal.ROUND_UP:
                mode = RoundingMode.UP;
                break;
            case BigDecimal.ROUND_DOWN:
                mode = RoundingMode.DOWN;
                break;
            case BigDecimal.ROUND_HALF_UP:
                mode = RoundingMode.HALF_UP;
                break;
            default:
                mode = RoundingMode.UP;
                break;
        }

        return mode;
    }

    /*
     * 1、ROUND_UP：向远离零的方向舍入。

 若舍入位为非零，则对舍入部分的前一位数字加1；若舍入位为零，则直接舍弃。即为向外取整模式。

        2、ROUND_DOWN：向接近零的方向舍入。

 不论舍入位是否为零，都直接舍弃。即为向内取整模式。

        3、ROUND_CEILING：向正无穷大的方向舍入。

 若 BigDecimal 为正，则舍入行为与 ROUND_UP 相同；若为负，则舍入行为与 ROUND_DOWN 相同。即为向上取整模式。

        4、ROUND_FLOOR：向负无穷大的方向舍入。

 若 BigDecimal 为正，则舍入行为与 ROUND_DOWN 相同；若为负，则舍入行为与 ROUND_UP 相同。即为向下取整模式。

        5、ROUND_HALF_UP：向“最接近的”整数舍入。

若舍入位大于等于5，则对舍入部分的前一位数字加1；若舍入位小于5，则直接舍弃。即为四舍五入模式。

        6、ROUND_HALF_DOWN：向“最接近的”整数舍入。

若舍入位大于5，则对舍入部分的前一位数字加1；若舍入位小于等于5，则直接舍弃。即为五舍六入模式。

        7、ROUND_HALF_EVEN：向“最接近的”整数舍入。

若（舍入位大于5）或者（舍入位等于5且前一位为奇数），则对舍入部分的前一位数字加1；

若（舍入位小于5）或者（舍入位等于5且前一位为偶数），则直接舍弃。即为银行家舍入模式。

        8、ROUND_UNNECESSARY

断言请求的操作具有精确的结果，因此不需要舍入。

如果对获得精确结果的操作指定此舍入模式，则抛出ArithmeticException。
     */

    /**
     * 对金额进行整数化
     *
     * @param amt
     *            金额
     * @param intUnit
     *            整数化单位类型
     * @param intTyp
     *            整数化方法
     * @return 整数化后的金额
     */
    public static BigDecimal parseAmt(BigDecimal amt, Long intUnit, String intTyp) {
        if (StringUtils.isEmpty(intTyp)) {

            throw new RuntimeException();
            
        }
        RoundingMode roundingMode = transRounding(intTyp); // 获得整数化方法
        if (roundingMode == null) {
            throw new RuntimeException();
        }
        amt = amt.setScale(intUnit.intValue(), roundingMode);
        return amt; // 进行整数化
    }
    
    /**
     * 转换小数点保留模式
     *
     * @param intType
     * @return
     */
    public static RoundingMode transRounding(String intType) {
        RoundingMode mode = null;
        switch (intType.charAt(0)) {
            case 'H':
                mode = RoundingMode.UP;
                break;
            case 'L':
                mode = RoundingMode.DOWN;
                break;
            case 'R':
                mode = RoundingMode.HALF_UP;
                break;
			default:
				mode = RoundingMode.UP;
				break;
        }
        
        return mode;
    }
    


    /**
     * 把list集合拆分成指定条数的集合
     * map.put(key,list)
     * map.put(key,list);
     * @param listObject  拆分的集合
     * @param splitCount  每一个集合多少条
     * @return
     */
    public static <T> Map<Integer, List<T>> splitListToMap(List<T> listObject, Integer splitCount){
        if(null==listObject || null==splitCount || splitCount<=0){
            return new HashMap<>();
        }
        Map<Integer, List<T>> resultMap = new HashMap<>();
        List<T> list = new ArrayList<>();
        Integer count = 0;
        for(T object:listObject){
            count++;
            list.add(object);
            if (list.size() == splitCount) {
                resultMap.put(count, list);
                list = new ArrayList<>();
            }
        }
        if (!list.isEmpty()) {
            resultMap.put(count, list);
        }
        return resultMap;
    }
    /*
     * 判断是否为整数
     * @param str 传入的字符串
     * @return 是整数返回true,否则返回false
     */
    public static boolean isInteger(String str) {
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }

    /**
     * KEY比较.
     *
     * @param obj1
     * @param obj2
     * @return 0 equal,-n 小于, n 大于。
     */
    public static int keyCompare(Object  obj1, Object obj2) {
        int compare = 0;
        if( obj1 instanceof Date && obj2 instanceof Date){
            //compare = DateUtil.compareDate((Date)obj1,(Date)obj2);
        }
        else if ( obj1 instanceof BigDecimal && obj2 instanceof BigDecimal){
            compare = compareMoney(toBigDecimal(obj1),toBigDecimal(obj2));
        }
        else if ( obj1 instanceof Integer && obj2 instanceof Integer){
            compare = compare(toInteger(obj1),toInteger(obj2));
        }
        else if ( obj1 instanceof Long && obj2 instanceof Long){
            compare = compare(toLong(obj1),toLong(obj2));
        }
        else {
            compare = compare(obj1.toString(),obj2.toString());
        }

        return compare;
    }

    // Map的key值降序排序
    public static <K extends Comparable<? super K>, V > Map<K, V> keyDescend(Map<K, V> map) {
        List<Map.Entry<K, V>> list = new ArrayList<>(map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
            @Override
            public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
                return -keyCompare(o1.getKey().toString(),o2.getKey().toString());
            }
        });
        
        Map<K, V> returnMap = new LinkedHashMap<K, V>();
        for (Map.Entry<K, V> entry : list) {
            returnMap.put(entry.getKey(), entry.getValue());
        }
        return returnMap;
    }



    // Map的key值升序排序
    public static <K  extends Comparable<? super K>, V> Map<K, V> keyAscend(Map<K, V> map) {
        List<Map.Entry<K, V>> list = new ArrayList<Map.Entry<K, V>>(map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
            @Override
            public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
                return keyCompare(o1.getKey(),o2.getKey());
            }
        });
        
        Map<K, V> returnMap = new LinkedHashMap<K, V>();
        for (Map.Entry<K, V> entry : list) {
            returnMap.put(entry.getKey(), entry.getValue());
        }
        return returnMap;
    }
    // Map的value值降序排序
    public static <K, V extends Comparable<? super V>> Map<K, V> valueDescend(Map<K, V> map) {
        List<Map.Entry<K, V>> list = new ArrayList<>(map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
            @Override
            public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
                return -keyCompare(o1.getValue(),o2.getValue());
            }
        });
        
        Map<K, V> returnMap = new LinkedHashMap<K, V>();
        for (Map.Entry<K, V> entry : list) {
            returnMap.put(entry.getKey(), entry.getValue());
        }
        return returnMap;
    }
    
    // Map的value值升序排序
    public static <K, V extends Comparable<? super V>> Map<K, V> valueAscend(Map<K, V> map) {
        List<Map.Entry<K, V>> list = new ArrayList<Map.Entry<K, V>>(map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
            @Override
            public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
                return keyCompare(o1.getValue(),o2.getValue());
            }
        });
        
        Map<K, V> returnMap = new LinkedHashMap<K, V>();
        for (Map.Entry<K, V> entry : list) {
            returnMap.put(entry.getKey(), entry.getValue());
        }
        return returnMap;
    }



    public static Map<String, Object> sortDescMapByKey(Map<String, Object> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }

        Map<String, Object> sortMap = new TreeMap<>(new MapKeyComparator());

        sortMap.putAll(map);

        return sortMap;
    }

    static class MapKeyComparator
            implements Comparator<String>
    {
        public int compare(String str1, String str2) {
            return str1.compareTo(str2);
        }
    }


    public static <K extends Comparable, V extends Comparable> Map<K, V> sortMapByValues(Map<K, V> aMap) {
        HashMap<K, V> finalOut = new LinkedHashMap<>();
        aMap.entrySet()
                .stream()
                .sorted((p1, p2) -> p2.getValue().compareTo(p1.getValue()))
                .collect(Collectors.toList()).forEach(ele -> finalOut.put(ele.getKey(), ele.getValue()));
        return finalOut;
    }
    public static Map<String, String> mapLenSort(Map<String, String> map){
    //map按 key 键值长度排序
    Map<String, String> treeMap = new TreeMap<String, String>(
            new Comparator<String>() {
                @Override
                public int compare(String s1, String s2) {
                    if (s1.length() > s2.length()) {
                        return -1;
                    } else if (s1.length() < s2.length()) {
                        return 1;
                    } else {
                        return s1.compareTo(s2);//if equal return alphabetical order
                    }
                }
            });
        treeMap.putAll(map);
        return treeMap;
    }



    /**
     *
     * @param str
     * @param prefix
     * @return
     */
    public static boolean startsWith(CharSequence str, CharSequence prefix) {
        return startsWith(str, prefix, false);
    }

    private static boolean startsWith(CharSequence str, CharSequence prefix, boolean ignoreCase) {
        if (str != null && prefix != null) {
            return prefix.length() > str.length() ? false : regionMatches(str, ignoreCase, 0, prefix, 0, prefix.length());
        } else {
            return str == null && prefix == null;
        }
    }

    private static boolean regionMatches(CharSequence cs, boolean ignoreCase, int thisStart, CharSequence substring, int start, int length) {
        if (cs instanceof String && substring instanceof String) {
            return ((String)cs).regionMatches(ignoreCase, thisStart, (String)substring, start, length);
        } else {
            int index1 = thisStart;
            int index2 = start;
            int tmpLen = length;
            int srcLen = cs.length() - thisStart;
            int otherLen = substring.length() - start;
            if (thisStart >= 0 && start >= 0 && length >= 0) {
                if (srcLen >= length && otherLen >= length) {
                    while(tmpLen-- > 0) {
                        char c1 = cs.charAt(index1++);
                        char c2 = substring.charAt(index2++);
                        if (c1 != c2) {
                            if (!ignoreCase) {
                                return false;
                            }

                            if (Character.toUpperCase(c1) != Character.toUpperCase(c2) && Character.toLowerCase(c1) != Character.toLowerCase(c2)) {
                                return false;
                            }
                        }
                    }

                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        }
    }
    private static String toUnderlineCase(String name) {
        if (isEmpty(name))
            return name;
        while (name.startsWith("_"))
            name = name.substring(1);
        while (name.endsWith("_"))
            name = name.substring(0, name.length() - 1);

        int po = name.indexOf("_");
        if (po >= 0)
            return name.toUpperCase();
        String wd = "";
        for (int i = 0; i < name.length(); i++) {
            char c = name.charAt(i);
            if (i > 0 && (Character.isDigit(c) || Character.isUpperCase(c))) {
                wd += "_" + Character.toUpperCase(c);
            } else {
                wd += Character.toUpperCase(c);
            }
        }
        return wd;
    }

    private static String toCamelCase(String name) {
        if (isEmpty(name))
            return name;
        while (name.startsWith("_"))
            name = name.substring(1);
        while (name.endsWith("_"))
            name = name.substring(0, name.length() - 1);
        int po = name.indexOf("_");

        if (po < 0)
            return name;

        String wd = name.substring(0, po);
        String left = name.substring(po + 1);
        wd = wd.substring(0, 1).toUpperCase() + wd.substring(1).toLowerCase();
        name = wd;
        po = left.indexOf("_");
        while (po >= 0) {
            wd = left.substring(0, po);
            wd = wd.substring(0, 1).toUpperCase() + wd.substring(1).toLowerCase();
            name += wd;

            left = left.substring(po + 1);
            po = left.indexOf("_");
        }
        if (!isEmpty(left)) {
            wd = left;
            wd = wd.substring(0, 1).toUpperCase() + wd.substring(1).toLowerCase();
            name += wd;
        }
        return name;
    }

    /**
     * 数据字典名转换：转换成小写驼峰命名.
     *
     * @param name
     * @return
     */
    public static String toLowerCamelCase(String name) {
        if (isEmpty(name))
            return name;
        while (name.startsWith("_"))
            name = name.substring(1);
        while (name.endsWith("_"))
            name = name.substring(0, name.length() - 1);
        int po = name.indexOf("_");
        if (po >= 0)
            name = toCamelCase(name);
        return name.substring(0, 1).toLowerCase() + name.substring(1);
    }

    /**
     * 数据字典名转换：转换成大写驼峰命名.
     *
     * @param name
     * @return
     */
    public static String toUpperCamelCase(String name) {
        if (isEmpty(name))
            return name;
        while (name.startsWith("_"))
            name = name.substring(1);
        while (name.endsWith("_"))
            name = name.substring(0, name.length() - 1);
        int po = name.indexOf("_");
        if (po >= 0)
            name = toCamelCase(name);
        return name.substring(0, 1).toUpperCase() + name.substring(1);
    }

    /**
     * 数据字典名转换：转换成小写下划线连字命名.<br>
     * 注意：转换规则，碰到大写字母、数字就增加连字符"_". <br>
     *
     * @param name
     * @return
     */
    public static String toLowerUnderlineCase(String name) {
        if (isEmpty(name))
            return name;
        return toUnderlineCase(name).toLowerCase();
    }

    /**
     * 数据字典名转换：转换成大写下划线连字命名. <br>
     * 注意：转换规则，碰到大写字母、数字就增加连字符"_". <br>
     *
     * @param name
     * @return
     */
    public static String toUpperUnderlineCase(String name) {
        if (isEmpty(name))
            return name;
        return toUnderlineCase(name).toUpperCase();
    }

    /**
     *截取两个特定字符之间的字符串
     * @param str
     * @param start
     * @param end
     * @return
     */
    public static String cutString(String str, String start, String end) {
        if (isEmpty(str)) {
            return str;
        }
        String reg= start + "(.*)" + end;
        Pattern pattern = Pattern.compile(reg);
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            str = matcher.group(1);
        }
        return str;
    }

}
